﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Lm.Common.Barcode
{
    public class Code128
    {
        protected List<Code128Item> ItemList { get; set; }
        public Code128(List<Code128Item> ItemList)
        {
            this.ItemList = ItemList;
        }

        public Code128()
            : this(global::Lm.Common.Barcode.Resource1.Code128)
        { }

        public Code128(string str)
        {
            System.Xml.Linq.XDocument doc = System.Xml.Linq.XDocument.Load(new System.IO.StringReader(str));
            var root = doc.Element("Code128Items");
            this.ItemList = new List<Code128Item>();
            foreach (var xe in root.Elements())
            {
                ItemList.Add(new Code128Item()
                {
                    ID = int.Parse(xe.Element("ID").Value),
                    BandCode = xe.Element("BandCode").Value,
                    Code128A = xe.Element("Code128A").Value,
                    Code128B = xe.Element("Code128B").Value,
                    Code128C = xe.Element("Code128C").Value,
                    Draw = xe.Element("Draw").Value,
                });
            }
        }

        public System.Drawing.Bitmap DrawCode128B(int BaseWith, int Height, string str)
        {
            if (!System.Text.RegularExpressions.Regex.IsMatch(str, "^[a-z,A-Z,0-9]{1,32}$"))
            { throw new Exception("输入的字符串不符合要求"); }
            List<Code128Item> Items = new List<Code128Item>();
            Items.Add(this.GetItemByID(104));
            foreach (char ch in str)
            {
                Items.Add(this.GetItemByCode128BChar(ch));
            }
            Items.Add(this.GetCheck(Items));
            Items.Add(this.GetItemByID(106));
            string Draw = this.GetDraw(Items);
            System.Drawing.Bitmap img = new System.Drawing.Bitmap(Draw.Length * BaseWith, Height);
            using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(img))
            {
                g.FillRectangle(System.Drawing.Brushes.White, 0, 0, img.Width, img.Height);
                for (int i = 0; i < Draw.Length; i++)
                {
                    System.Drawing.Pen pen;
                    if (Draw[i] == 'b')
                    { pen = System.Drawing.Pens.Black; }
                    else
                    { pen = System.Drawing.Pens.White; }
                    for (int j = 0; j < BaseWith; j++)
                    {
                        g.DrawLine(pen, new System.Drawing.Point(BaseWith * i + j, 0), new System.Drawing.Point(BaseWith * i + j, Height - 1));
                    }
                }
                g.Dispose();
            }
            return img;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Items">包含起始项和数据项</param>
        /// <returns></returns>
        protected Code128Item GetCheck(List<Code128Item> Items)
        {
            int count = Items.First().ID;
            for (int i = 1; i < Items.Count; i++)
            {
                count += (i * Items[i].ID);
            }
            int checkID = count % 103;
            return this.GetItemByID(checkID);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Items">所有项</param>
        /// <returns></returns>
        protected string GetDraw(List<Code128Item> Items)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var i in Items)
            {
                sb.Append(i.Draw);
            }
            return sb.ToString();
        }
        protected Code128Item GetItemByID(int ID)
        {
            var result = (from i in this.ItemList where i.ID == ID select i).Single();
            return result;
        }
        protected Code128Item GetItemByCode128BChar(char ch)
        {
            var result = (from i in this.ItemList where i.Code128B == ch.ToString() select i).Single();
            return result;
        }


    }
}
